// Copyright 2012 Sergio, Raul, Dorival. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// STL
#include <iostream>
#include <cmath>

// GemLab
#include "gemlab.h"

using std::cout;
using std::endl;
using GemLab::Vec_t;
using GemLab::Mat_t;
using GemLab::Array;
using GemLab::String;
using GemLab::Geo2name;
using GemLab::Geo2nvc;
using GemLab::Geo2gnd;
using GemLab::Geo2natc;
using GemLab::Geo2func;
using GemLab::TRI3;
using GemLab::Cell;

int checkXR(Vec_t & X, Vec_t & R, Vec_t const & Rcor, double Tol)
{
    int nerr = 0;
    for (int i=0; i<X.rows(); ++i) {
        if (fabs(R(i) - Rcor[i]) > Tol) nerr += 1;
    }
    if (X.rows() > 2) {
        cout << "X = " << X(0) << ", " << X(1) << ", " << X(2) << "  =>  ";
        cout << "R = " << R(0) << ", " << R(1) << ", " << R(2);
    } else {
        cout << "X = " << X(0) << ", " << X(1) << "  =>  ";
        cout << "R = " << R(0) << ", " << R(1);
    }
    if (nerr>0) cout << "[1;31m ERROR[0m";
    else        cout << "[1;32m OK[0m";
    cout << endl;
    return nerr;
}

int main(int argc, char **argv) try
{
    GemLab::Mesh mesh(/*NDim*/2);
    mesh.SetSize   (6/*verts*/, 4/*cells*/);
    mesh.SetVert   (0, -100, 0.0, 0.0, 0);
    mesh.SetVert   (1, -101, 0.0, 2.0, 0);
    mesh.SetVert   (2,    0, 2.0, 0.0, 0);
    mesh.SetVert   (3,    0, 2.0, 1.5, 0);
    mesh.SetVert   (4,    0, 4.0, 0.0, 0);
    mesh.SetVert   (5,    0, 4.0, 1.0, 0);
    mesh.SetCell   (0,   -1, TRI3, Array<int>(0,2,3));
    mesh.SetCell   (1,   -1, TRI3, Array<int>(3,1,0));
    mesh.SetCell   (2,   -1, TRI3, Array<int>(2,4,5));
    mesh.SetCell   (3,   -1, TRI3, Array<int>(5,3,2));
    mesh.SetBryTag (1, 0, -10);
    mesh.SetBryTag (3, 0, -10);
    mesh.WriteVTU  ("doc_msh1");
    mesh.WriteMPY  ("doc_msh1");

    int    nerr = 0;
    double tol  = 1.0e-17;

    Vec_t X(2), R(2), Rcor(2);
    X << 0.0, 0.0;
    Rcor << 0.0, 0.0;
    Cell const * c = mesh.Cells[0];
    CellInvMap(c, X, R);
    nerr += checkXR(X, R, Rcor, tol);

    X << 2.0, 0.0;
    Rcor << 1.0, 0.0;
    CellInvMap(c, X, R);
    nerr += checkXR(X, R, Rcor, tol);

    X << 2.0, 1.5;
    Rcor << 0.0, 1.0;
    CellInvMap(c, X, R);
    nerr += checkXR(X, R, Rcor, tol);

    if (nerr>0) return 1;
    return 0;
}
GEMLAB_CATCH
